package com.ling.module1sbbyyds.service.community;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.yitter.idgen.YitIdHelper;
import com.ling.sbbyyds.common.validator.ValidatorUtils;
import com.ling.sbbyyds.entity.community.CommunityPosts;
import com.ling.sbbyyds.entity.community.CommunityPostsCollect;
import com.ling.sbbyyds.entity.community.CommunityPostsLike;
import com.ling.sbbyyds.entity.exception.ApiWarningInfoException;
import com.ling.sbbyyds.entity.users.User;
import com.ling.sbbyyds.interaction.vo.CommunityPostsVo;
import com.ling.sbbyyds.interaction.vo.CommunityPostsDetailVo;
import com.ling.sbbyyds.interaction.param.CommunityPostsPo;

import com.ling.module1sbbyyds.service.news.usercenter.UserAttService;
import com.ling.module1sbbyyds.utils.FileLocalStorageTool;
import com.ling.module1sbbyyds.utils.PageUtil;
import com.ling.module1sbbyyds.utils.UserThreadLocal;
import com.ling.sbbyyds.attribute.FixedAttribute;
import com.ling.sbbyyds.common.PageUtils;
import com.ling.sbbyyds.common.QueryApiUtils;
import com.ling.sbbyyds.imagetools.ImageUtils;
import com.ling.sbbyyds.interaction.ResultVo;
import com.ling.sbbyyds.mapper.community.CommunityPostCollectMapper;
import com.ling.sbbyyds.mapper.community.CommunityPostLikeMapper;
import com.ling.sbbyyds.mapper.community.CommunityPostsMapper;
import com.ling.sbbyyds.mapper.user.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 天道酬勤、学无止境
 *
 * @Description: 社区帖子
 * @author: ling
 * @date: 2022年03月27日
 */
@Slf4j
@Service
public class CommunityPostService {
    @Autowired(required = false)
    private CommunityPostsMapper communityPostsMapper;
    @Autowired(required = false)
    private UserMapper userMapper;
    @Autowired
    private FileLocalStorageTool fileLocalStorageTool;
    @Autowired
    private UserAttService userAttService;
    @Autowired
    private CommunityPostLikeMapper postLikeMapper;
    @Autowired
    private CommunityPostCollectMapper postCollectMapper;


    /**
     * 帖子图片 存储文件夹
     */
    private static String POSTS_IMAGE_PATH = "articleFile";

    /**
     * 获取帖子
     *
     * @param page             页数
     * @param limit            一页数据数
     * @param communityPostsPo 查询条件
     * @return 查询帖子数据
     */
    public ResultVo getCommunityPostsList(Integer page, Integer limit, CommunityPostsPo communityPostsPo) {
        Example example = new Example(CommunityPosts.class);
        //新建一个 筛选条件对象
        Example.Criteria criteria = example.createCriteria();
        if (!ObjectUtils.isEmpty(communityPostsPo.getTalkId())) {
            criteria.andEqualTo("talkId", communityPostsPo.getTalkId());
        }
        if (!ObjectUtils.isEmpty(communityPostsPo.getTalkTypeId())) {
            criteria.andEqualTo("talkTypeId", communityPostsPo.getTalkTypeId());
        }
        if (!ObjectUtils.isEmpty(communityPostsPo.getSearchInfo())) {
            criteria.andEqualTo("title", communityPostsPo.getSearchInfo());
            criteria.andEqualTo("content", communityPostsPo.getSearchInfo());
        }
        criteria.andEqualTo("isDel", 0);
        example.setOrderByClause("release_time desc");
        //进行分页查找
        List<CommunityPosts> communityPostsList;
        if (!ObjectUtils.isEmpty(page) && !ObjectUtils.isEmpty(limit)) {
            final PageInfo<CommunityPosts> pageInfo = PageHelper.startPage(page, limit)
                    .doSelectPageInfo(() -> this.communityPostsMapper.selectByExample(example));
            communityPostsList = pageInfo.getList();
        } else {//不分页
            communityPostsList = communityPostsMapper.selectByExample(example);
        }
        //总条数
        int count = 0;
        //不为空
        if (!ObjectUtils.isEmpty(communityPostsList)) {
            count = communityPostsMapper.selectCountByExample(example);
        }

        return ResultVo.success(getOrderInfo(communityPostsList)).put("count", count);
    }

    /**
     * 发布帖子
     * form-data请求，，携带图片文件
     *
     * @param communityPostsPo 文章信息参数
     * @param files            图片文件
     * @return 成功反馈
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVo releaseCommunityPost(CommunityPostsPo communityPostsPo, MultipartFile[] files) throws Throwable {
        CommunityPosts communityPosts = new CommunityPosts();
        BeanUtils.copyProperties(communityPostsPo, communityPosts);

        ArrayList<String> images = new ArrayList<>();

        //存在图片就进行上传
        String filePath;
        if (!ObjectUtils.isEmpty(files)) {
            ValidatorUtils.isException(files.length > 9)
                    .throwMessage("文件过多！", ApiWarningInfoException.class);
            for (MultipartFile file : files) {
                filePath = fileLocalStorageTool.uploadImage(POSTS_IMAGE_PATH, 1, file);
                //存放图片url
                images.add(filePath);
            }
        }
        //将文件数据转为json格式
        String o = JSON.toJSON(images).toString();
        //将文件数据存到数据库
        communityPosts.setImageList(o);
        // 获取发布者
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        //设置文章id
        long newId = YitIdHelper.nextId();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String ipAddress = new QueryApiUtils().getIpAddress((String) userData.get("ip"));

        communityPosts.setPostsId(newId)
                .setReleaseTime(sdf.parse(sdf.format(System.currentTimeMillis())))
                .setUserId(user.getId())
                .setIpAddress(ipAddress)
                .setViewNum(0);
        communityPostsMapper.insertSelective(communityPosts);
        //插入帖子成功
        return ResultVo.success(newId, "发布成功！");
    }

    /**
     * 发布帖子
     * json请求携带图片base64
     *
     * @param communityPostsPo 文章信息参数
     * @return 成功反馈
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVo releaseCommunityPost(CommunityPostsPo communityPostsPo) throws Exception {
        CommunityPosts communityPosts = new CommunityPosts();
        BeanUtils.copyProperties(communityPostsPo, communityPosts);

        ArrayList<String> images = new ArrayList<>();
        List<String> base64Images = communityPostsPo.getBase64Images();

        //存在图片就进行上传
        String filePath;
        if (!ObjectUtils.isEmpty(communityPostsPo.getBase64Images())) {
            if (communityPostsPo.getBase64Images().size() > 9) {
                return ResultVo.fail("文件过多！");
            }
            for (String image : base64Images) {
                filePath = fileLocalStorageTool.uploadBase64Image(POSTS_IMAGE_PATH, image);
                //存放图片url
                images.add(filePath);
            }
        }
        // 将文件数据转为json格式,将文件数据存到数据库
        communityPosts.setImageList(JSON.toJSON(images).toString());
        // 获取发布者
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        //设置文章id
        long newId = YitIdHelper.nextId();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String ipAddress = new QueryApiUtils().getIpAddress((String) userData.get("ip"));
        communityPosts.setPostsId(newId)
                .setReleaseTime(sdf.parse(sdf.format(System.currentTimeMillis())))
                .setUserId(user.getId())
                .setIpAddress(ipAddress)
                .setViewNum(0);
        communityPostsMapper.insert(communityPosts);
        //插入帖子成功
        return ResultVo.success();
    }

    /**
     * @param id: 用户id
     * @Description: 获取用户所有的未删除帖子
     * @author: ling
     * @date: 2022/5/9
     */
    public ResultVo getAuthorPosts(Long id) {
        if (ObjectUtils.isEmpty(id)) {
            return ResultVo.fail("用户id不能为空！");
        }
        int count = 0;
        List<CommunityPosts> communityPosts = userMapper.selectPostsListById(id);
        if (!ObjectUtils.isEmpty(communityPosts)) {
            count = userMapper.selectPostsCountById(id);
        }
        return ResultVo.success(getOrderInfo(communityPosts)).put("count", count);
    }

    /**
     * 补全帖子信息
     *
     * @param communityPosts 帖子列表
     * @return
     */
    private List<CommunityPostsVo> getOrderInfo(List<CommunityPosts> communityPosts) {
        //  将帖子信息转交给返回列表对象
        List<CommunityPostsVo> communityPostsVos = new ArrayList<>();
        try {
            for (CommunityPosts communityPost : communityPosts) {
                CommunityPostsVo communityPostsVo = new CommunityPostsVo();
                BeanUtils.copyProperties(communityPost, communityPostsVo);

                communityPostsVo.setImageList(ImageUtils.convertJsonToImageUrlList(communityPost.getImageList()));

                //  查出用户的名称与头像
                User user = userMapper.selectByPrimaryKey(communityPost.getUserId());
                if (user != null) {
                    communityPostsVo.setUserName(user.getUserName());
                    communityPostsVo.setUserAvatar(ImageUtils.convertImageUrl(user.getAvatar()));
                }
                communityPostsVos.add(communityPostsVo);
            }

            Map<String, Object> userData = UserThreadLocal.get();
            User userInfo;
            if (!ObjectUtils.isEmpty(userData)) {
                userInfo = (User) userData.get("user");
                if (!ObjectUtils.isEmpty(userInfo)) {
                    for (CommunityPostsVo communityPost : communityPostsVos) {
                        //关注状态
                        communityPost.setAttFlag(userAttService.getAttUserFlag(userInfo.getId(), communityPost.getUserId(), true));
                    }
                }
            } else {
                for (CommunityPostsVo communityPost : communityPostsVos) {
                    //关注状态
                    communityPost.setAttFlag(false);
                }
            }
        } catch (BeansException e) {
            e.printStackTrace();
        }
        return communityPostsVos;
    }

    /**
     * 获取帖子详情
     *
     * @param postId 帖子id
     * @return
     */
    public ResultVo getPostDetail(Long postId) {
        Long userId;
        try {
            Map<String, Object> userData = UserThreadLocal.get();
            User userInfo = (User) userData.get("user");
            userId = userInfo.getId();
        } catch (NullPointerException e) {
            userId = null;
        }

        CommunityPostsDetailVo postDetail = communityPostsMapper.getPostDetail(postId, userId);
        if (!ObjectUtils.isEmpty(postDetail)) {
            postDetail.setImageList(ImageUtils.convertJsonToImageUrl(postDetail.getImageList()));
            postDetail.setUserAvatar(ImageUtils.convertImageUrl(postDetail.getUserAvatar()));
            if (!ObjectUtils.isEmpty(userId)) {
                //关注状态
                postDetail.setAttFlag(userAttService.getAttUserFlag(userId, postDetail.getUserId(), true));
                //收藏状态
                postDetail.setDianZanFlag(postLikeMapper.userIsLikePost(userId, postId) > 0);
                //点赞状态
                postDetail.setCollectFlag(postCollectMapper.userIsLikePost(userId, postId) > 0);
            } else {
                postDetail.setAttFlag(false);
                postDetail.setDianZanFlag(false);
                postDetail.setCollectFlag(false);
            }

        }
        return ResultVo.success(postDetail);
    }

    /**
     * 获取关注用户发的贴
     *
     * @param page  页数
     * @param limit 条数
     * @return
     */
    public ResultVo getAttUserRePosts(Integer page, Integer limit) {
        // 获取用户id
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");

        Integer[] startEndPage = PageUtil.getStartEndPage(page, limit);
        List<CommunityPostsVo> attUserRePosts = communityPostsMapper.getAttUserRePosts(startEndPage[0], startEndPage[1], user.getId());
        for (CommunityPostsVo attUserRePost : attUserRePosts) {
            attUserRePost.setUserAvatar(ImageUtils.convertImageUrl(attUserRePost.getUserAvatar()));
            attUserRePost.setImageList(ImageUtils.convertJsonToImageUrlList(attUserRePost.getImageListStr()));
        }
        return ResultVo.success(attUserRePosts).put("count", communityPostsMapper.getAttUserRePostsCount(user.getId()));
    }

    /**
     * 点赞帖子
     *
     * @param postsLike 内容
     * @param type      true：点赞  false：取消点赞
     * @return
     */
    public ResultVo likePosts(CommunityPostsLike postsLike, Boolean type) {
        //查询帖子点赞数和id
        CommunityPosts communityPosts = communityPostsMapper.getPostLikeNum(postsLike.getPostId());

        if (ObjectUtils.isEmpty(communityPosts)) {
            return ResultVo.fail("帖子不存在");
        }

        // 获取用户id
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        postsLike.setUserId(user.getId());

        // 点赞
        if (type) {
            postsLike.setId(YitIdHelper.nextId());
            communityPosts.setDianZanNum(communityPosts.getDianZanNum() + 1);
            postLikeMapper.insert(postsLike);
        } else {
            // 取消点赞
            communityPosts.setDianZanNum(communityPosts.getDianZanNum() - 1);

            //删除点赞记录
            Example example = new Example(CommunityPostsLike.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("postId", postsLike.getPostId());
            criteria.andEqualTo("userId", postsLike.getUserId());
            postLikeMapper.deleteByExample(example);
        }

        communityPostsMapper.updateByPrimaryKeySelective(communityPosts);
        return ResultVo.success("true");
    }

    /**
     * 收藏帖子
     *
     * @param postsCollect 内容
     * @param type         true：收藏  false：取消收藏
     * @return
     */
    public ResultVo collectPosts(CommunityPostsCollect postsCollect, Boolean type) {
        //查询帖子点赞数和id
        CommunityPosts communityPosts = communityPostsMapper.getPostCollectNum(postsCollect.getPostId());
        Integer collectNum = communityPosts.getCollectNum();

        if (ObjectUtils.isEmpty(communityPosts)) {
            return ResultVo.fail("帖子不存在");
        }

        // 获取用户id
        Map<String, Object> userData = UserThreadLocal.get();
        User user = (User) userData.get("user");
        postsCollect.setUserId(user.getId());

        // 收藏
        if (type) {
            postsCollect.setId(YitIdHelper.nextId());
            communityPosts.setCollectNum(ObjectUtils.isEmpty(collectNum) ? 1 : collectNum + 1);
            postCollectMapper.insert(postsCollect);
        } else {
            // 取消收藏
            communityPosts.setCollectNum(collectNum - 1);

            // 删除收藏记录
            Example example = new Example(CommunityPostsCollect.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("postId", postsCollect.getPostId());
            criteria.andEqualTo("userId", postsCollect.getUserId());
            postCollectMapper.deleteByExample(example);
        }

        communityPostsMapper.updateByPrimaryKeySelective(communityPosts);
        return ResultVo.success("true");
    }


    /**
     * 分页查询用户的公开帖子
     *
     * @param userId   用户ID
     * @param pageCode 页码
     * @param limit    页数据量
     * @return 用户帖子数据
     */
    public ResultVo getUserPostsList(String userId, Integer pageCode, Integer limit) {
        // 查询帖子原数据
        LambdaQueryWrapper<CommunityPosts> postsQuery = new LambdaQueryWrapper<>();
        postsQuery.eq(CommunityPosts::getUserId, userId)
                .eq(CommunityPosts::getIsPrivate, FixedAttribute.USER_POST_IS_PRIVATE_FALSE)
                .orderByDesc(CommunityPosts::getReleaseTime);
        Page<CommunityPosts> postsPageList = communityPostsMapper.selectPage(PageUtils.initPage(pageCode, limit), postsQuery);

        List<CommunityPosts> records = postsPageList.getRecords();
        ArrayList<CommunityPostsVo> communityPostsVos = new ArrayList<>();
        records.forEach(item -> {
            CommunityPostsVo communityPostsVo = new CommunityPostsVo();
            BeanUtils.copyProperties(item, communityPostsVo);
            communityPostsVo.setImageList(ImageUtils.convertJsonToImageUrlList(item.getImageList()));
            communityPostsVos.add(communityPostsVo);
        });
        return ResultVo.success(PageUtils.beautifyField(postsPageList).setList(communityPostsVos));
    }

    /**
     * 更新帖子查看权限
     *
     * @param postId 帖子ID
     * @param status 更新状态 不为空则按这个字段更新，为空则自动取反
     * @return 返回更新反馈
     */
    public ResultVo updatePostsPrivilege(String postId, Integer status) {
        User currentUser = UserThreadLocal.getCurrentUser();
        CommunityPosts communityPosts = communityPostsMapper.selectByPrimaryKey(postId);
        if (!ObjectUtils.isEmpty(communityPosts) &&
                !currentUser.getId().equals(communityPosts.getUserId())) {
            throw new ApiWarningInfoException("没有修改权限！");
        }
        if (ObjectUtils.isEmpty(status)) {
            status = FixedAttribute.USER_POST_IS_PRIVATE_TRUE.equals(communityPosts.getIsPrivate()) ? 0 : 1;
            communityPosts.setIsPrivate(status);
        } else {
            switch (status) {
                case 0:
                    communityPosts.setIsPrivate(FixedAttribute.USER_POST_IS_PRIVATE_FALSE);
                    break;
                case 1:
                    communityPosts.setIsPrivate(FixedAttribute.USER_POST_IS_PRIVATE_TRUE);
                    break;
                default:
                    throw new ApiWarningInfoException("状态值错误！");
            }
        }
        communityPostsMapper.updateByPrimaryKeySelective(communityPosts);
        return ResultVo.success();
    }

    /**
     * 删除帖子
     *
     * @param postId 帖子Id
     * @return 反馈
     */
    public ResultVo deletePosts(String postId) {
        User currentUser = UserThreadLocal.getCurrentUser();
        CommunityPosts communityPosts = communityPostsMapper.selectByPrimaryKey(postId);
        communityPosts.setIsDel(FixedAttribute.DATA_IS_DELETE_TURE);
        communityPostsMapper.updateByPrimaryKeySelective(communityPosts);
        return ResultVo.success();
    }
}
